package process

import (
	"encoding/json"
	"fmt"
	"go_chat_system/common"
	"go_chat_system/common/entity"
	"go_chat_system/common/status"
	"go_chat_system/server/model"
	"go_chat_system/server/utils"
	"net"
)

// 账户相关的处理器
type AccountProcess struct {
	Conn net.Conn
	// 当前用户编号
	UserId int
}

var (
	user  entity.Account
	reply common.MessageReply
)

// 处理登录
func (this *AccountProcess) Login(userStr string) (err error) {
	// 反序列化
	err = json.Unmarshal([]byte(userStr), &user)
	// 登录验证
	user, err = model.MyAccountDao.Login(user.UserId, user.Password)
	//fmt.Println(user)
	if err != nil { // 登陆失败
		if err == model.ERROR_USER_NOTEXISTS { // 用户不存在
			reply = common.MessageReply{
				Code:  404,
				Error: err.Error(),
			}
		} else {
			reply = common.MessageReply{
				Code:  -255,
				Error: err.Error(),
			}
		}
	} else { // 登陆成功
		// 将当前用户，添加到在线用户表里
		this.UserId = user.UserId
		userMgr.AddOnlineUser(this)
		// 通知其他在线用户
		this.NotifyOtherOnlineUsers(this.UserId)
		// 查询当前所有在线用户id列表
		allOnlineUser := userMgr.GetAllOnlineUser()
		users := make(map[int]entity.Account, len(allOnlineUser))
		for id, u := range allOnlineUser {
			users[id] = entity.Account{
				UserId:   u.UserId,
				UserName: user.UserName,
				Status:   status.UserOnline,
			}
		}
		//fmt.Printf("OnlineUser:%v,Type:%T\n", users, users)
		reply = common.MessageReply{
			Code:   255,
			Result: users,
		}
	}

	return writeData(this.Conn, common.LoginReply, reply)
}

func (this *AccountProcess) Register(userStr string) (err error) {
	// 反序列化
	err = json.Unmarshal([]byte(userStr), &user)
	// 入库
	err = model.MyAccountDao.Register(&user)
	if err != nil { // 注册失败
		if err == model.ERROR_USER_EXISTS { // 已存在
			reply = common.MessageReply{
				Code:  0,
				Error: err.Error(),
			}
		} else {
			reply = common.MessageReply{
				Code:  -255,
				Error: err.Error(),
			}
		}
	} else {
		reply = common.MessageReply{
			Code: 255,
		}
	}
	return writeData(this.Conn, common.RegisterReply, reply)
}

// 将MessageReply返回给客户端
func writeData(conn net.Conn, messageType string, reply common.MessageReply) (err error) {
	// 序列化MessageReply
	data, err := json.Marshal(reply)
	// 序列化Message
	mess := common.Message{
		Type: messageType,
		Data: string(data),
	}
	data, err = json.Marshal(mess)
	// 发送给客户端
	transfer := &utils.Transfer{
		Conn: conn,
	}
	return transfer.WriteData(data)
}

// 通知其他在线用户
func (this *AccountProcess) NotifyOtherOnlineUsers(userId int) {
	// 遍历所有在线用户列表，逐一发送UserId上线了
	for id, up := range userMgr.GetAllOnlineUser() {
		// 过滤当前登录用户
		if id != userId {
			data := createUserStatusMessage(userId)
			// 通知该用户，UserId登录了
			up.NotifyUserOnline(data)
		}
	}
}

// 生成用户状态信息
func createUserStatusMessage(userId int) (data []byte) {
	// 用户状态变化
	notifyMes := common.NotifyUserStatusMessage{
		UserId: userId,
		Status: status.UserOnline, //在线
	}
	data, err := json.Marshal(notifyMes)
	if err != nil {
		fmt.Println("createUserStatusMessage Marshal User Status Message Error", err)
		return
	}
	// 通知内容
	mes := common.Message{
		Type: common.NotifyUserStatusMessageType,
		Data: string(data),
	}
	data, err = json.Marshal(mes)
	if err != nil {
		fmt.Println("createUserStatusMessage Marshal Message Error", err)
		return
	}
	return
}

// 通知该用户，UserId登录了
func (this *AccountProcess) NotifyUserOnline(data []byte) {
	// 发送给客户端
	err := (&utils.Transfer{
		Conn: this.Conn,
	}).WriteData(data)

	if err != nil {
		fmt.Println("NotifyUserOnline WriteData Error", err)
		return
	}
}
